package com.tool.app.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JacksonUtil {

	private static final Logger logger = LoggerFactory.getLogger(JacksonUtil.class);

	private JacksonUtil() {
	}

	private static final String STANDARD_PATTERN = "yyyy-MM-dd HH:mm:ss";
	private static final String DATE_PATTERN = "yyyy-MM-dd";

	/**
	 * 配置ObjectMapper对象
	 */
	private static final ObjectMapper objectMapper = new ObjectMapper();

	static {


		objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
		//null的属性不进行序列化
		objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		//序列化的时候序列对象的那些属性
		//JsonInclude.Include.NON_DEFAULT 属性为默认值不序列化
		//JsonInclude.Include.ALWAYS      所有属性
		//JsonInclude.Include.NON_EMPTY   属性为 空（“”） 或者为 NULL 都不序列化
		//JsonInclude.Include.NON_NULL    属性为NULL 不序列化
		objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
		//反序列化时,遇到未知属性会不会报错
		//true - 遇到没有的属性就报错 false - 没有的属性不会管，不会报错
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		 //开启单引号解析属性，默认是false
		objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
		//开启属性名没有引号的非标准json字符串
		//objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
		//可解析正无穷、负无穷或NaN 数字类型值 默认是false
		objectMapper.configure(JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS, true);
		//反序列化可解析以”0”为开头的数字 , 默认是false
		objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
		//设置解析能识别JSON串里的反斜杠注释符
		objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
		//开启JSON字符串包含非引号控制字符的解析（\n换行符） 默认false 遇到这些字符会抛异常
		//objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
		// 忽略 transient 修饰的属性
		objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
		//修改序列化后日期格式
		objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		objectMapper.registerModule(new JavaTimeModule());
		//处理不同的时区偏移格式
		objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);


	}

	/**
	 * 对象拷贝
	 */
	public static <T> T convertValue(Object fromValue, Class<T> toValueType) {
		try {
			return objectMapper.convertValue(fromValue, toValueType);
		} catch (Exception e) {
			logger.error("convertValue exception", e);
		}
		return null;
	}

	public static <T> T readValue(String content, Class<T> valueType) {
		try {
			return objectMapper.readValue(content, valueType);
		} catch (Exception e) {
			logger.error("readValue exception", e);
		}
		return null;
	}


	public static <T> List<T> jsonToList(String jsonString,Class<T> cls) {
		try {
			return objectMapper.readValue(jsonString, TypeFactory.defaultInstance().constructCollectionType(List.class, cls));
		} catch (Exception e) {
			logger.error("jsonToList exception", e);
		}
		return null;
	}

	/**
	 * json字符串转成map
	 */
	public static <T> Map<String, T> jsonToErasedMap(String jsonString) {
		try {
			return objectMapper.readValue(jsonString, new TypeReference<HashMap<String, T>>(){} );
		} catch (Exception e) {
			logger.error("jsonToMaps exception", e);
		}
		return null;
	}

	/**
	 * json字符串转成map
	 */
	public static <T> Map<String, T> jsonToMap(String jsonString, Class<T> valueType) {
		try {
			return objectMapper.readValue(jsonString, TypeFactory.defaultInstance().constructMapType(Map.class, String.class, valueType));
		} catch (Exception e) {
			logger.error("jsonToMaps exception", e);
		}
		return null;
	}



	public static String toJSon(Object object) {
		try {
			return objectMapper.writeValueAsString(object);
		} catch (Exception e) {
			logger.error("toJSon exception", e);
		}
		return null;
	}

	public static void main(String[] args) {

	}
}
